#ifndef __DEFENS_OMIT_BRANCH_H
#define __DEFENS_OMIT_BRANCH_H

#include "llvm/Module.h"
#include "llvm/LLVMContext.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Constants.h"
#include "llvm/BasicBlock.h"
#include "llvm/Pass.h"
#include "llvm/Support/CFG.h"
#include "llvm/Analysis/DebugInfo.h"

#include "../../../../include/util.h"
#include "../../../../idm/id.h"
#include "../sync-func/sync-func.h"

#include "../../include/tern/TernDefs.h"

using namespace llvm;
using namespace std;
using namespace __gnu_cxx;

namespace defens {

	struct OmitBranch: public ModulePass {

		static char ID;

		OmitBranch(): ModulePass(&ID) {
			SF = NULL;
		}

		virtual void getAnalysisUsage(AnalysisUsage &AU) const;
		virtual bool runOnModule(Module &M);
		virtual void print(raw_ostream &O, const Module *M) const;
		bool omit(BranchInst *branch);
		Long_To_Int_Map &getBrInstOmitted() {return brInstOmitted;};

	private:
		void simple_test(Module &M); // for test purpose
		void dfs(BasicBlock *x, BasicBlock *sink);

		SyncFunc *SF;
		DenseMap<BasicBlock *, bool> visited;
		Long_To_Int_Map brInstOmitted;
	};
}

#endif
